﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using NetBay.Core.BusinessEntities;
using Rio.Applications.Web.Services;
using System.ServiceModel.DomainServices.Client;
using Rio.Framework.Pages.CriteriaControls;
using Rio.Framework.Pages.AppCode.Models;
using System.ComponentModel;
using System.Windows.Data;
using NetBay.Core.BusinessEntities.Workflow;
using Rio.Framework.Localisation;
using Rio.Framework.Pages.ChildWindows;

namespace Rio.Framework.Pages.ChildWindows
{
    public partial class RemindWindow : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

        #region Fields

        private RemindWindowDisplayMode _mode;
        private List<Document> m_oDocumentList;
        private MessageFlowDisp m_oMessage;
        private List<Group> _allGroups;
        private List<Group> m_oSelectedMailTo;
        private string m_sObject = string.Empty;
        private WorkflowInstance _workflowInstance;
        private bool _remindWorkflowReceiver;
        private List<WorkflowInstanceUser> _workflowInstanceUsers;
        private string _workflowInstanceUsersFormatted;

        #endregion Fields

        #region Constructors

        public RemindWindow()
        {
            InitializeComponent();

            this.CanMove = false;
            this.ResizeMode = Telerik.Windows.Controls.ResizeMode.NoResize;
            this.WindowStartupLocation = Telerik.Windows.Controls.WindowStartupLocation.CenterScreen;

            InitLabels();

            GetGroupList();
        }

        public RemindWindow(List<Document> p_oDocumentList, MessageFlowDisp p_oMessage)
            : this()
        {
            Mode = RemindWindowDisplayMode.ClassicMode;

            m_oDocumentList = p_oDocumentList;
            m_oMessage = p_oMessage;
            ObjectTextBox.Text = p_oMessage.Objet;
            ToTextBox.Text = p_oMessage.DestinataireList;
            MemoTextBox.Text = p_oMessage.Memo + "\r\r--------------------\r\r ";
            foreach (Document l_oDoc in p_oDocumentList)
            {
                MemoTextBox.Text += l_oDoc.OriginalNameFile + "\r";
            }
        }

        public RemindWindow(WorkflowInstance workflowInstance)
            : this()
        {
            _workflowInstance = workflowInstance;
            Mode = RemindWindowDisplayMode.WorkflowMode;
            RemindWorkflowReceiver = true;
            ObjectTextBox.Text = String.Format(Resx.GetLabel(ResxFlowPage.REMIND_WORKFLOW_OBJECT_FORMAT), _workflowInstance.DefinitionName, _workflowInstance.CreatedOn);

            //Retrieve all users concerned by the workflow instance
            BusinessEntitiesDomainContext businessEntitiesDomainContext = new BusinessEntitiesDomainContext();
            var getUserInstancesQuery = businessEntitiesDomainContext.GetUserInstancesQuery(_workflowInstance.Identifier);
            businessEntitiesDomainContext.Load<WorkflowInstanceUser>(
                getUserInstancesQuery,
                GetUserInstancesQueryCallBack,
                null);
        }

        #endregion Constructors

        #region Properties

        public bool RemindWorkflowReceiver
        {
            get { return _remindWorkflowReceiver; }
            set
            {
                _remindWorkflowReceiver = value;
                OnPropertyChanged("RemindWorkflowReceiver");

                UpdateWorkflowReceiverMode();
            }
        }
        public List<Group> GetMailTo
        {
            get
            {
                return m_oSelectedMailTo;
            }
        }
        public RemindWindowDisplayMode Mode
        {
            get { return _mode; }
            set
            {
                _mode = value;
                OnPropertyChanged("Mode");
            }
        }

        #endregion Properties

        #region Methods

        /// <summary>
        /// Updates the workflow receiver mode.
        /// </summary>
        private void UpdateWorkflowReceiverMode()
        {
            if (_allGroups != null
                && _workflowInstance != null)
            {
                if (RemindWorkflowReceiver)
                {
                    //Display all receivers of workflow
                    ToTextBox.Text = _workflowInstance.GroupName;
                }
                else
                {
                    //Display all receivers of workflow that they have do no action
                    ToTextBox.Text = String.Join(";", _workflowInstanceUsers.Select(i => i.GroupName));
                }
            }
        }

        /// <summary>
        /// Gets the user instances query call back.
        /// </summary>
        /// <param name="result">The result.</param>
        private void GetUserInstancesQueryCallBack(LoadOperation<WorkflowInstanceUser> result)
        {
            _workflowInstanceUsers = result.Entities.Where(u => u.LastActionId == 0).ToList();
            
            UpdateWorkflowReceiverMode();
        }

        /// <summary>
        /// Call back method binding the lis of group to the Grid
        /// </summary>
        /// <param name="result">List of group</param>
        public void OnGetGroupListQueryCallback(LoadOperation<Group> result)
        {
            List<Group> l_oGroups = new List<Group>(result.Entities);
            if ((l_oGroups != null) && (l_oGroups.Count > 0))
            {
                _allGroups = l_oGroups;

                if (_mode == RemindWindowDisplayMode.ClassicMode)
                {
                    m_oSelectedMailTo = new List<Group>();
                    String[] l_oGroupString = m_oMessage.DestinataireList.Split(new char[] { ';' });

                    foreach (string str in l_oGroupString)
                    {
                        if (!string.Empty.Equals(str))
                        {
                            foreach (Group l_oGroup in l_oGroups)
                            {
                                if (l_oGroup.Name.Equals(str))
                                {
                                    m_oSelectedMailTo.Add(l_oGroup);
                                }
                            }
                        }
                    }
                }
                else
                {
                    UpdateWorkflowReceiverMode();
                }
            }
        }

        /// <summary>
        /// Handles the Click event of the buttonCancel control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.Windows.RoutedEventArgs"/> instance containing the event data.</param>
        private void buttonCancel_Click(object sender, RoutedEventArgs e)
        {
            this.DialogResult = false;
            this.Close();
        }

        /// <summary>
        /// Event raised on button send click
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void buttonSend_Click(object sender, RoutedEventArgs e)
        {
            if (ValidateFields())
            {
                this.IsEnabled = false;

                BusinessEntitiesDomainContext l_oBEDomainContext = new BusinessEntitiesDomainContext();
                ((WebDomainClient<BusinessEntitiesDomainContext.IBusinessEntitiesDomainServiceContract>)l_oBEDomainContext.DomainClient).ChannelFactory.Endpoint.Binding.SendTimeout = new TimeSpan(1, 0, 0);

                var l_oEmailQuery = l_oBEDomainContext.RemindQuery(ObjectTextBox.Text, MemoTextBox.Text, ToTextBox.Text);
                l_oBEDomainContext.Load(l_oEmailQuery, OnEmailQueryCallback, null);
            }
            else
            {
                ValidatorMsg.Visibility = Visibility.Visible;
            }
        }

        private void buttonTo_Click(object sender, RoutedEventArgs e)
        {
            GroupFilterWindow L_oGroupFilterWindow = new GroupFilterWindow(m_oMessage.DestinataireList, true);
            L_oGroupFilterWindow.Closed += L_oGroupFilterWindow_Closed;
            L_oGroupFilterWindow.ShowDialog();
        }

        /// This method Get the group list and bind it to the grid
        /// </summary>
        /// <returns>A list of group</returns>
        private List<Group> GetGroupList()
        {
            BusinessEntitiesDomainContext l_oBEDomainContext = new BusinessEntitiesDomainContext();
            ((WebDomainClient<BusinessEntitiesDomainContext.IBusinessEntitiesDomainServiceContract>)l_oBEDomainContext.DomainClient).ChannelFactory.Endpoint.Binding.SendTimeout = new TimeSpan(1, 0, 0);

            var GroupList_Query = l_oBEDomainContext.GetAllGroupQuery();
            l_oBEDomainContext.Load(GroupList_Query, OnGetGroupListQueryCallback, null);

            return null;
        }

        /// <summary>
        /// Inits the label.
        /// </summary>
        private void InitLabels()
        {
            buttonSend.Content = Resx.GetLabel(ResxFlowPage.SEND);
            buttonCancel.Content = Resx.GetLabel(ResxCommon.CANCEL);
            ButtonTo.Content = Resx.GetLabel(ResxFlowPage.TO);
            LabelObject.Content = Resx.GetLabel(ResxFlowPage.OBJECT);
            LabelMemo.Content = Resx.GetLabel(ResxFlowPage.MEMO);
            ValidatorMsg.Text = Resx.GetLabel(ResxAlert.VALIDATE_MSG);
            checkbox_Workflow_ReceiverType1.Content = Resx.GetLabel(ResxFlowPage.REMIND_WORKFLOW_RECEIVERTYPE1);
            checkbox_Workflow_ReceiverType2.Content = Resx.GetLabel(ResxFlowPage.REMIND_WORKFLOW_RECEIVERTYPE2);
            Header = Resx.GetLabel(ResxFlowPage.REMIND);
            remindTypeLabel.Content = Resx.GetLabel(ResxFlowPage.REMIND_REMINDTYPE);
        }

        /// <summary>
        /// Group filter window event closing
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void L_oGroupFilterWindow_Closed(object sender, EventArgs e)
        {
            GroupFilterWindow L_oGroupFilterWindow = (GroupFilterWindow)sender;

            //if a value has been selected
            if (L_oGroupFilterWindow.DialogResult == true)
            {
                try
                {
                    List<Group> l_oGroupList = L_oGroupFilterWindow.m_szSelectedItems;
                    if (l_oGroupList != null && l_oGroupList.Count > 0)
                    {
                        m_oSelectedMailTo = new List<Group>();
                        ToTextBox.Text = l_oGroupList[0].Name;
                        if (l_oGroupList.Count > 1)
                        {
                            for (int i = 1; i < l_oGroupList.Count; i++)
                            {
                                ToTextBox.Text += ";" + l_oGroupList[i].Name;
                                m_oSelectedMailTo.Add(l_oGroupList[i]);
                            }
                        }

                    }

                }
                catch (Exception)
                {
                    //Logger.Write("CANNOT GET SELECTED GROUP : " + Environment.NewLine + ex, Logger.Level.Error);
                }
            }
        }

        /// <summary>
        /// Email query callback
        /// </summary>
        /// <param name="result"></param>
        private void OnEmailQueryCallback(LoadOperation<ReturnObject> result)
        {
            this.IsEnabled = true;

            if (result.Error != null)
            {
                //Logger.Write("EXCEPTION : " + Environment.NewLine + result.Error, Logger.Level.Error);
            }
            else
            {
                this.DialogResult = true;
                this.Close();
            }
        }

        /// <summary>
        /// Validates the fields.
        /// </summary>
        /// <returns></returns>
        private bool ValidateFields()
        {
            bool l_bValidationResult = true;

            if (string.IsNullOrEmpty(ToTextBox.Text))
            {
                l_bValidationResult = false;
            }

            if (string.IsNullOrEmpty(ObjectTextBox.Text))
            {
                l_bValidationResult = false;
            }

            return l_bValidationResult;
        }

        /// <summary>
        /// Called when [property changed].
        /// </summary>
        /// <param name="propertyName">Name of the property.</param>
        protected void OnPropertyChanged(string propertyName)
        {
            if (this.PropertyChanged != null)
            {
                this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }

        #endregion Methods
    }

    #region Enums

    public enum RemindWindowDisplayMode
    {
        ClassicMode = 0,
        WorkflowMode = 1
    }

    #endregion

    #region Converters

    public class RemindWindowDisplayModeToVisibilityConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            RemindWindowDisplayMode mode = (RemindWindowDisplayMode)Enum.Parse(typeof(RemindWindowDisplayMode), System.Convert.ToString(value), true);

            return mode == RemindWindowDisplayMode.ClassicMode ? Visibility.Collapsed : Visibility.Visible;
        }

        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }

    public class RemindWindowDsplayModeToBooleanConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            RemindWindowDisplayMode mode = (RemindWindowDisplayMode)Enum.Parse(typeof(RemindWindowDisplayMode), System.Convert.ToString(value), true);

            return mode == RemindWindowDisplayMode.ClassicMode;
        }

        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            return (bool) value ? RemindWindowDisplayMode.ClassicMode : RemindWindowDisplayMode.WorkflowMode;
        }
    }

    #endregion
}